from fastapi import Request
import os
import logging
from typing import Optional, Dict, Any, List

class WxCloudRunHeader:
    """
    微信云托管请求头处理公共类
    
    用于从请求头中获取微信相关信息，包括OpenID、AppID、UnionID等
    以及从环境变量中获取云托管环境信息
    """
    
    # 微信云托管请求头
    WX_HEADER_OPENID = "X-WX-OPENID"  # 小程序用户 openid
    WX_HEADER_APPID = "X-WX-APPID"  # 小程序 AppID
    WX_HEADER_UNIONID = "X-WX-UNIONID"  # 小程序用户 unionid
    WX_HEADER_FROM_OPENID = "X-WX-FROM-OPENID"  # 资源复用情况下，小程序用户 openid
    WX_HEADER_FROM_APPID = "X-WX-FROM-APPID"  # 资源复用情况下，使用方小程序 AppID
    WX_HEADER_FROM_UNIONID = "X-WX-FROM-UNIONID"  # 资源复用情况下，小程序用户 unionid
    WX_HEADER_ENV = "X-WX-ENV"  # 所在云环境 ID
    WX_HEADER_SOURCE = "X-WX-SOURCE"  # 调用来源
    WX_HEADER_CLIENT_IP = "X-Original-Forwarded-For"  # 客户端 IPv4 或IPv6 地址
    WX_HEADER_SIGNATURE = "x-signature"  # 签名
    WX_HEADER_TIMESTAMP = "x-timestamp"  # 时间戳
    WX_HEADER_NONCE = "x-nonce"  # 随机数
    
    # 环境变量
    ENV_ID = "CBR_ENV_ID"  # 当前环境 ID
    MYSQL_USERNAME = "MYSQL_USERNAME"  # 数据库用户名
    MYSQL_PASSWORD = "MYSQL_PASSWORD"  # 数据库密码
    MYSQL_ADDRESS = "MYSQL_ADDRESS"  # 数据库内网地址
    
    @staticmethod
    async def get_all_headers(request: Request) -> Dict[str, str]:
        """
        获取所有请求头信息
        
        参数:
        - request: FastAPI请求对象
        
        返回:
        - 所有请求头信息的字典
        """
        headers = {}
        for key, value in request.headers.items():
            headers[key.lower()] = value
        return headers
    
    @staticmethod
    async def get_openid(request: Request) -> Optional[str]:
        """
        获取用户OpenID
        
        参数:
        - request: FastAPI请求对象
        
        返回:
        - 用户OpenID，如果不存在则返回None
        """
        openid = request.headers.get(WxCloudRunHeader.WX_HEADER_OPENID)
        if not openid:
            # 如果不存在普通的OpenID，尝试获取资源复用情况下的OpenID
            openid = request.headers.get(WxCloudRunHeader.WX_HEADER_FROM_OPENID)
        return openid
    
    @staticmethod
    async def get_appid(request: Request) -> Optional[str]:
        """
        获取小程序AppID
        
        参数:
        - request: FastAPI请求对象
        
        返回:
        - 小程序AppID，如果不存在则返回None
        """
        appid = request.headers.get(WxCloudRunHeader.WX_HEADER_APPID)
        if not appid:
            # 如果不存在普通的AppID，尝试获取资源复用情况下的AppID
            appid = request.headers.get(WxCloudRunHeader.WX_HEADER_FROM_APPID)
        return appid
    
    @staticmethod
    async def get_unionid(request: Request) -> Optional[str]:
        """
        获取用户UnionID
        
        参数:
        - request: FastAPI请求对象
        
        返回:
        - 用户UnionID，如果不存在则返回None
        """
        unionid = request.headers.get(WxCloudRunHeader.WX_HEADER_UNIONID)
        if not unionid:
            # 如果不存在普通的UnionID，尝试获取资源复用情况下的UnionID
            unionid = request.headers.get(WxCloudRunHeader.WX_HEADER_FROM_UNIONID)
        return unionid
    
    @staticmethod
    async def get_env_id(request: Request) -> Optional[str]:
        """
        获取云环境ID
        
        参数:
        - request: FastAPI请求对象
        
        返回:
        - 云环境ID，如果不存在则返回None
        """
        return request.headers.get(WxCloudRunHeader.WX_HEADER_ENV)
    
    @staticmethod
    async def get_source(request: Request) -> Optional[str]:
        """
        获取调用来源
        
        参数:
        - request: FastAPI请求对象
        
        返回:
        - 调用来源，如果不存在则返回None
        """
        return request.headers.get(WxCloudRunHeader.WX_HEADER_SOURCE)
    
    @staticmethod
    async def get_client_ip(request: Request) -> Optional[str]:
        """
        获取客户端IP地址
        
        参数:
        - request: FastAPI请求对象
        
        返回:
        - 客户端IP地址，如果不存在则返回None
        """
        return request.headers.get(WxCloudRunHeader.WX_HEADER_CLIENT_IP)
    
    @staticmethod
    async def is_from_wx_ecosystem(request: Request) -> bool:
        """
        判断请求是否来自微信生态（小程序或公众号H5）
        
        参数:
        - request: FastAPI请求对象
        
        返回:
        - 如果来自微信生态则返回True，否则返回False
        """
        return WxCloudRunHeader.WX_HEADER_SOURCE in request.headers
    
    @staticmethod
    async def get_signature(request: Request) -> Optional[str]:
        """
        获取签名
        
        参数:
        - request: FastAPI请求对象
        
        返回:
        - 签名，如果不存在则返回None
        """
        return request.headers.get(WxCloudRunHeader.WX_HEADER_SIGNATURE)
    
    @staticmethod
    async def get_timestamp(request: Request) -> Optional[str]:
        """
        获取时间戳
        
        参数:
        - request: FastAPI请求对象
        
        返回:
        - 时间戳，如果不存在则返回None
        """
        return request.headers.get(WxCloudRunHeader.WX_HEADER_TIMESTAMP)
    
    @staticmethod
    async def get_nonce(request: Request) -> Optional[str]:
        """
        获取随机数
        
        参数:
        - request: FastAPI请求对象
        
        返回:
        - 随机数，如果不存在则返回None
        """
        return request.headers.get(WxCloudRunHeader.WX_HEADER_NONCE)
    
    @staticmethod
    def get_environment_variable(name: str) -> Optional[str]:
        """
        获取环境变量
        
        参数:
        - name: 环境变量名称
        
        返回:
        - 环境变量值，如果不存在则返回None
        """
        return os.getenv(name)
    
    @staticmethod
    def get_current_env_id() -> Optional[str]:
        """
        获取当前云环境ID
        
        返回:
        - 当前云环境ID，如果不存在则返回None
        """
        return os.getenv(WxCloudRunHeader.ENV_ID)
    
    @staticmethod
    def get_mysql_config() -> Dict[str, Optional[str]]:
        """
        获取MySQL配置信息
        
        返回:
        - MySQL配置信息的字典，包括用户名、密码和地址
        """
        return {
            "username": os.getenv(WxCloudRunHeader.MYSQL_USERNAME),
            "password": os.getenv(WxCloudRunHeader.MYSQL_PASSWORD),
            "address": os.getenv(WxCloudRunHeader.MYSQL_ADDRESS)
        }
    
    @staticmethod
    def get_all_env_variables() -> Dict[str, str]:
        """
        获取所有环境变量
        
        返回:
        - 所有环境变量的字典
        """
        return dict(os.environ)
    
    @staticmethod
    async def log_request_info(request: Request) -> None:
        """
        记录请求相关信息到日志
        
        参数:
        - request: FastAPI请求对象
        """
        headers = await WxCloudRunHeader.get_all_headers(request)
        openid = await WxCloudRunHeader.get_openid(request)
        appid = await WxCloudRunHeader.get_appid(request)
        
        logging.info(f"请求路径: {request.url.path}")
        logging.info(f"请求方法: {request.method}")
        logging.info(f"请求头: {headers}")
        logging.info(f"用户OpenID: {openid}")
        logging.info(f"小程序AppID: {appid}")
        
        is_wx_request = await WxCloudRunHeader.is_from_wx_ecosystem(request)
        logging.info(f"是否来自微信生态: {is_wx_request}")